/**
 * Copyright (c) 2016-2020 https://github.com/zhaohuatai
 *
 * contact 824069438@qq.com
 *  
 */
package org.zfes.snowy.ss.config.configrations;

import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.handler.UnauthorizedHandler;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.client.RestTemplate;
import org.zfes.snowy.auth.shiro.cache.manger.ShiroRedisCacheManager;
import org.zfes.snowy.auth.shiro.credential.SnowyCredentialsMatcher;
import org.zfes.snowy.auth.shiro.filter.authc.SnowyCapchaProducerFilter;
import org.zfes.snowy.auth.shiro.filter.authc.SnowyLoginPassThruAuthenticationFilter;
import org.zfes.snowy.auth.shiro.filter.authc.SnowyLogoutFilter;
import org.zfes.snowy.auth.shiro.filter.authc.SnowyTokenAuthenticationFilter;
import org.zfes.snowy.auth.shiro.filter.csrf.CSRFTokenFilter;
import org.zfes.snowy.auth.shiro.filter.sso.SSOSyncCenterfilter;
import org.zfes.snowy.auth.shiro.filter.sso.SSOSyncClientFilter;
import org.zfes.snowy.auth.shiro.handlers.IAuthecFailureHandler;
import org.zfes.snowy.auth.shiro.handlers.IAuthecLogoutHandler;
import org.zfes.snowy.auth.shiro.handlers.IAuthecSuccessHandler;
import org.zfes.snowy.auth.shiro.handlers.IUnAuthecHandler;
import org.zfes.snowy.auth.shiro.handlers.SimpleAuthecCsrfFailureHandler;
import org.zfes.snowy.auth.shiro.handlers.SimpleAuthecFailureHandler;
import org.zfes.snowy.auth.shiro.handlers.SimpleAuthecLogoutHandler;
import org.zfes.snowy.auth.shiro.handlers.SimpleAuthecSuccessHandler;
import org.zfes.snowy.auth.shiro.handlers.SimpleUnauthecHandler;
import org.zfes.snowy.auth.shiro.handlers.SimpleUnauthorizedHandler;
import org.zfes.snowy.auth.shiro.jwt.filter.SnowyJwtAuthTokenFilter;
import org.zfes.snowy.auth.shiro.jwt.mgt.SnowySessionStorageEvaluator;
import org.zfes.snowy.auth.shiro.realm.MultiSubjectRealm;
import org.zfes.snowy.auth.shiro.realm.SnowyRemoteRealm;
import org.zfes.snowy.auth.shiro.remote.IRemoteAuthService;
import org.zfes.snowy.auth.shiro.remote.RemoteAuthServiceImpl;
import org.zfes.snowy.auth.shiro.session.dao.SnowyShiroSessionDAO;
import org.zfes.snowy.auth.shiro.session.repository.impl.RedisShiroSessionRepository;
//import org.zfes.snowy.auth.shiro.session.validate.SnowyExecutorServiceSessionValidationScheduler;
import org.zfes.snowy.auth.shiro.suser.SessionUserManager;
import org.zfes.snowy.auth.shiro.weichat.auhec.SnowyWeiChatAuthenticationFilter;
import org.zfes.snowy.core.exceptions.AppRuntimeException;
import org.zfes.snowy.core.util.AppCtxUtil;
import org.zfes.snowy.core.util.ZObjectUtil;
import org.zfes.snowy.core.util.ZStrUtil;
import org.zfes.snowy.httpinvoke.SnowyAuthHttpInvokerServiceExporter;
import org.zfes.snowy.ss.config.properties.ShiroConfigProperties;
import org.zfes.snowy.ss.config.properties.ShiroWeiChatConfigProperties;

import com.google.code.kaptcha.Producer;

import org.zfes.snowy.auth.AuthConsts;
import org.zfes.snowy.auth.manager.AuthManagerImpl;
@Configuration
@ConditionalOnProperty(name = "shiro.isClientApp", havingValue = "false", matchIfMissing = true)
public class SnowyShiroConfiguration {
	//http://blog.csdn.net/u012345283/article/details/44199791
   @Autowired
   private ShiroConfigProperties shiroConfigProperties; 
   @Autowired
   private ShiroWeiChatConfigProperties shiroWeiChatConfigProperties; 
   @Autowired
   private Producer producer;
	@Autowired  
    private RestTemplate restTemplate;
	@Autowired
	private SessionUserManager sessionUserManager;
	@Autowired  
	private  ApplicationEventPublisher publisher;
 //-------------------------------------------------------------------------------------------------------------------
   /**
    * shiro 自定义过滤器不能声明为全局的，roxiedFilterChain
    * 全局会导致else 之前的代码执行，执行容器级别的filter，  shiro里已经执行过一次了，，容器级别的在执行一次就错了
    * @return
    */
	
	@Bean(name = "shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(){
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager());
		
		Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
		filters.put("capcha", capchaProducerFilter());
		filters.put("zlogout", logoutFilter());
		filters.put("zauthc", tokenAuthenticationFilter() );
		filters.put("weiauthc", weiChatAuthenticationFilter() );
		filters.put("csrf", csrfTokenFilter());
		filters.put("loginThrust", loginPassThruAuthenticationFilter());
		filters.put("ssoSyncCenter", ssoSyncCenterfilter());
		filters.put("ssoSyncClient", ssoSyncClientFilter());
		filters.put("jwt", jwtAuthTokenFilter());
		Map<String,String> cosumfilters=shiroConfigProperties.getFiltersMap();
		try {
			if(cosumfilters!=null&&!cosumfilters.isEmpty()){
				for(Map.Entry<String, String> entry : cosumfilters.entrySet()){
					String value=entry.getValue();
					String clazz=ZStrUtil.substringBeforeLast(value, ".");
					String methodName=ZStrUtil.substringAfterLast(value, ".");
					Method initmethod;
					initmethod = ReflectionUtils.findMethod(Class.forName(clazz), methodName);
					initmethod.setAccessible(true);
					filters.put(entry.getKey(), (Filter) ReflectionUtils.invokeMethod(initmethod, AppCtxUtil.getBean(Class.forName(clazz))));
				}
			
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		shiroFilterFactoryBean.setFilters(filters);
		Map<String,String> filterChainDefinitionMap= new LinkedHashMap<>();
		filterChainDefinitionMap.put(shiroConfigProperties.getSsoCenterSyncPath(), "ssoSyncCenter");
		filterChainDefinitionMap.put(shiroConfigProperties.getSsoClientSyncPath(), "ssoSyncClient");
		filterChainDefinitionMap.putAll(shiroConfigProperties.getFilterChainDefinitionMap());
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		
		return shiroFilterFactoryBean;
	}
	
//------------------------------------remoteAuthService-------------------------------------------------------------------------------
		   @Lazy(true)
		   @Bean(name="remoteAuthService")
		   @ConditionalOnProperty(name = "shiro.isClientApp", havingValue = "false", matchIfMissing = true)
		   public Object remoteAuthService(){
			   RemoteAuthServiceImpl remoteAuthService = new RemoteAuthServiceImpl();  
			   remoteAuthService.setSnowyRealm(authorizingRealm());
			   remoteAuthService.setSessionDAO(sessionDAO());
			   return remoteAuthService;  
		   } 
		   @Lazy(true)
		   @Bean(name="/remoteAuthService")
		   @ConditionalOnProperty(name = "shiro.isClientApp", havingValue = "false", matchIfMissing = true)
		   public HttpInvokerServiceExporter httpInvokerRemoteAuthServer(){    
				HttpInvokerServiceExporter bean = new SnowyAuthHttpInvokerServiceExporter(); 
				 bean.setService(remoteAuthService());
				 bean.setServiceInterface(IRemoteAuthService.class);
				return bean;  
		   } 
		   
		    @Bean(name = "authorizingRealm")
		    @DependsOn(value={"appCtxUtil"}) 
		    public SnowyRemoteRealm authorizingRealm() {  
		    	SnowyRemoteRealm userRealm=new MultiSubjectRealm();
		    	((MultiSubjectRealm)userRealm).setAuthManager(AppCtxUtil.getBean(AuthManagerImpl.class));
		    	userRealm.setAuthenticationCachingEnabled(shiroConfigProperties.getAuthenticationCachingEnabled());
		    	userRealm.setAuthenticationCachingEnabled(false);
		    	//userRealm.setAuthenticationCacheName(shiroConfigProperties.getAuthenticationCacheName()+"_"+AppCtxUtil.getAppKey().get());
		    	
		    	userRealm.setAuthorizationCachingEnabled(shiroConfigProperties.getAuthorizationCachingEnabled());
		    	//userRealm.setAuthorizationCacheName(shiroConfigProperties.getAuthorizationCacheName());
		       
		    	userRealm.setAuthorizationCacheName(shiroConfigProperties.getAuthorizationCacheName()+"_"+AppCtxUtil.getAppKey().get());
		    	
		        userRealm.setCredentialsMatcher(hashedCredentialsMatcher());
		        
		        userRealm.setCacheManager(shiroCacheManager()); 
		        userRealm.setAppKey(AppCtxUtil.getAppKey().get());
		        return userRealm;
		    }
//----------------------------------shiro---------------------------------------------------------------------------------	     
    @Bean(name="securityManager")  
    public DefaultWebSecurityManager securityManager() {  
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();  
        
        
        manager.setRealm(authorizingRealm());  
        manager.setCacheManager(shiroCacheManager());  
        manager.setSessionManager(sessionManager());  
        manager.setRememberMeManager(rememberMeManager());
        manager.setSubjectFactory(statelessDefaultSubjectFactory());
        //jwt 不产生session
        SnowySessionStorageEvaluator snowySessionStorageEvaluator=new SnowySessionStorageEvaluator();
		 snowySessionStorageEvaluator.setJwtTokenLoginUrl(AuthConsts.JWT.DEFAULT_JWT_LOGIN_SUBMIT_URL);
		 snowySessionStorageEvaluator.setSessionManager(sessionManager());
		( (DefaultSubjectDAO) manager.getSubjectDAO()).setSessionStorageEvaluator(snowySessionStorageEvaluator);
        return manager;  
    } 
    
    @Bean(name="defaultSubjectFactory")  
    public org.zfes.snowy.auth.shiro.jwt.mgt.StatelessDefaultSubjectFactory statelessDefaultSubjectFactory(){
    	return new org.zfes.snowy.auth.shiro.jwt.mgt.StatelessDefaultSubjectFactory();
    }
    @Bean(name="sessionManager")  
    public DefaultWebSessionManager sessionManager() {  
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();  
        sessionManager.setCacheManager(shiroCacheManager()); 
        
        sessionManager.setGlobalSessionTimeout(shiroConfigProperties.getGlobalSessionTimeout());  
        sessionManager.setDeleteInvalidSessions(shiroConfigProperties.getDeleteInvalidSessions());  
        sessionManager.setSessionValidationSchedulerEnabled(shiroConfigProperties.getSessionValidationSchedulerEnabled()); 
        
        //相互依赖
//         ExecutorServiceSessionValidationScheduler sessionValidationScheduler=sessionValidationScheduler();
//        SnowyExecutorServiceSessionValidationScheduler sessionValidationScheduler=sessionValidationScheduler();
//		 sessionValidationScheduler.setSessionManager(sessionManager);
//		 sessionManager.setSessionValidationScheduler(sessionValidationScheduler);
//		 sessionValidationScheduler.setShiroSessionRepository(jedisShiroSessionRepository());
         sessionManager.setSessionIdCookie(sessionIdCookie());
         sessionManager.setSessionIdCookieEnabled(shiroConfigProperties.getSessionIdCookieEnabled());
        
        sessionManager.setSessionDAO(sessionDAO());
        return sessionManager;  
    }  
    
//	 @Bean(name = "sessionValidationScheduler")
//	 public SnowyExecutorServiceSessionValidationScheduler sessionValidationScheduler() {
//		 SnowyExecutorServiceSessionValidationScheduler sessionValidationScheduler= new SnowyExecutorServiceSessionValidationScheduler();
//		 sessionValidationScheduler.setInterval(shiroConfigProperties.getInterval());
//		 sessionValidationScheduler.setUseRedisValidation(shiroConfigProperties.getUseRedisValidation());
//		 
//		// sessionValidationScheduler.setSessionManager(sessionManager());
//		return  sessionValidationScheduler;
//	 }
    
//	 @Bean(name = "sessionValidationScheduler")
//	 public ExecutorServiceSessionValidationScheduler sessionValidationScheduler() {
//		 ExecutorServiceSessionValidationScheduler sessionValidationScheduler= new ExecutorServiceSessionValidationScheduler();
//		 sessionValidationScheduler.setInterval(shiroConfigProperties.getInterval());
//		// sessionValidationScheduler.setSessionManager(sessionManager());
//		return  sessionValidationScheduler;
//	 }
	
	@Bean(name = "sessionDAO")
	public SessionDAO sessionDAO() {  
		if(shiroConfigProperties.getSessionDaoType().equals("EnterpriseCacheSessionDAO")){
			EnterpriseCacheSessionDAO sessionDAO=new EnterpriseCacheSessionDAO();
			sessionDAO.setActiveSessionsCache(shiroCacheManager().getCache(shiroConfigProperties.getActiveSessionsCacheName()));
			sessionDAO.setSessionIdGenerator(sessionIdGenerator());
			return sessionDAO;
		}else if(shiroConfigProperties.getSessionDaoType().equals("SnowyShiroSessionDAO")){
			SnowyShiroSessionDAO sessionDAO=new SnowyShiroSessionDAO();
			sessionDAO.setActiveSessionsCacheName(shiroConfigProperties.getActiveSessionsCacheName());
			sessionDAO.setGlobalSessionTimeout(shiroConfigProperties.getGlobalSessionTimeout());
			
			sessionDAO.setShiroSessionRepository(jedisShiroSessionRepository());
			sessionDAO.setSessionIdGenerator(sessionIdGenerator());
			return sessionDAO;
		}else{
			throw new AppRuntimeException("sessionDAO 类型配置错误，或者不支持");
		}
	}
	
	
	@Bean(name = "jedisShiroSessionRepository")
	@Lazy(true)
	@DependsOn({"redisSingleConfigration","redisShardConfigration"})
    public RedisShiroSessionRepository jedisShiroSessionRepository() {  
		RedisShiroSessionRepository redisShiroSessionRepository = new RedisShiroSessionRepository(); 
		Boolean isCluster=shiroConfigProperties.getShiroUseRedisCluster();
		if(isCluster==null||!isCluster){
			redisShiroSessionRepository.setJedisManager(AppCtxUtil.getBean(RedisSingleConfigration.class).JedisManager());
		}else{
			redisShiroSessionRepository.setJedisManager(AppCtxUtil.getBean(RedisShardConfigration.class).JedisManager());
		}
		//redisShiroSessionRepository.setJedisManager(redisSingleConfigration.JedisManager());
        return redisShiroSessionRepository;
    }
	

 
	@Bean(name = "hashedCredentialsMatcher")
	public SnowyCredentialsMatcher hashedCredentialsMatcher() {
		SnowyCredentialsMatcher credentialsMatcher = new SnowyCredentialsMatcher();
		credentialsMatcher.setHashAlgorithmName(shiroConfigProperties.getHashAlgorithmName());
		credentialsMatcher.setHashIterations(shiroConfigProperties.getHashIterations());
		credentialsMatcher.setStoredCredentialsHexEncoded(shiroConfigProperties.getStoredCredentialsHexEncoded());
		return credentialsMatcher;
	}
	
    @Bean(name = "shiroCacheManager")
    public CacheManager shiroCacheManager() {  
    	String shiroCacheType=shiroConfigProperties.getShiroCacheType();
    	if("ehcache".equals(shiroCacheType)){
    		EhCacheManager ehCacheManager = new EhCacheManager();  
    		ehCacheManager.setCacheManagerConfigFile(shiroConfigProperties.getCacheConfig());
    		return ehCacheManager; 
    	}else if("memory".equals(shiroCacheType)){
    		return new MemoryConstrainedCacheManager();
    	}else if("redis".equals(shiroCacheType)){
    		ShiroRedisCacheManager redisCacheManager=new  ShiroRedisCacheManager(); 
    		Boolean isCluster=shiroConfigProperties.getShiroUseRedisCluster();
    		if(isCluster==null||!isCluster){
    			redisCacheManager.setJedisManager(AppCtxUtil.getBean(RedisSingleConfigration.class).JedisManager());
    		}else{
    			redisCacheManager.setJedisManager(AppCtxUtil.getBean(RedisShardConfigration.class).JedisManager());
    		}
    		//redisCacheManager.setJedisManager(redisSingleConfigration.JedisManager());
    		return redisCacheManager;  
    	}
        throw new AppRuntimeException("缓存配置错误");  
    } 
    
    
    @Bean(name = "rememberMeManager")
    public RememberMeManager rememberMeManager() {  
    	CookieRememberMeManager rememberMeManager = new org.apache.shiro.web.mgt.CookieRememberMeManager(); 
    	byte[] cipherKey = Base64.decode(shiroConfigProperties.getRememberMePublickKey());
    	rememberMeManager.setCipherKey(cipherKey);
    	rememberMeManager.setCookie(rememberMeCookie() );
        return rememberMeManager;  
    }     
    
    @Bean(name = "sessionIdCookie")
	 public Cookie sessionIdCookie() {
    	SimpleCookie cookie=new org.apache.shiro.web.servlet.SimpleCookie(shiroConfigProperties.getSessionCookieName());
    	cookie.setHttpOnly(shiroConfigProperties.getSessionCookieHttpOnly());
    	cookie.setMaxAge(shiroConfigProperties.getSessionCookieMaxAge());
    	cookie.setName(shiroConfigProperties.getSessionCookieName());
	    return cookie;
	 }
    
    @Bean(name = "rememberMeCookie")
	 public Cookie rememberMeCookie() {
    	SimpleCookie cookie=new org.apache.shiro.web.servlet.SimpleCookie(shiroConfigProperties.getRememberMeCookieName());
    	cookie.setHttpOnly(shiroConfigProperties.getRememberMeCookieHttpOnly());
    	cookie.setMaxAge(shiroConfigProperties.getRememberMeCookieMaxAge());
	    return cookie;
	 }
    
     
  
	  @Bean(name = "sessionIdGenerator")
	  public SessionIdGenerator sessionIdGenerator() {
		  return new org.zfes.snowy.auth.shiro.session.idgen.SnowySessionIdGenerator();
		  //return new org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator();
	 }    
	 
	@Bean
	@ConditionalOnMissingBean
	@DependsOn("lifecycleBeanPostProcessor") 
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
	    DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
	    daap.setProxyTargetClass(true);
	    return daap;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
	   AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
	   aasa.setSecurityManager(securityManager);
	   return aasa;
	 }
	 
//------------------------------------------------------------------------------------------------
	
	  public SnowyJwtAuthTokenFilter jwtAuthTokenFilter() {  
			SnowyJwtAuthTokenFilter jwtAuthTokenFilter = new  SnowyJwtAuthTokenFilter(); 
			jwtAuthTokenFilter.setJwtAuthenticationFailureHandler(jwtAuthenticationFailureHandler());
			
		    return jwtAuthTokenFilter;  
	 } 
	  
	  
	  public SnowyLoginPassThruAuthenticationFilter loginPassThruAuthenticationFilter() {  
		  SnowyLoginPassThruAuthenticationFilter loginPassThruAuthenticationFilter= new SnowyLoginPassThruAuthenticationFilter(); 
		  setP( loginPassThruAuthenticationFilter );
	      return loginPassThruAuthenticationFilter; 
	  } 
	  
	  public SnowyTokenAuthenticationFilter tokenAuthenticationFilter() {  
		  SnowyTokenAuthenticationFilter tokenAuthenticationFilter = new  SnowyTokenAuthenticationFilter();  
		  setP( tokenAuthenticationFilter );
		  tokenAuthenticationFilter.setSessionUserManager(sessionUserManager);
		  tokenAuthenticationFilter.setPublisher(publisher);
	      return tokenAuthenticationFilter;  
	  } 
	  public SnowyWeiChatAuthenticationFilter weiChatAuthenticationFilter() {  
		  SnowyWeiChatAuthenticationFilter tokenAuthenticationFilter = new  SnowyWeiChatAuthenticationFilter(); 
		  tokenAuthenticationFilter.setRestTemplate(restTemplate);
		  tokenAuthenticationFilter.setSessionUserManager(sessionUserManager);
		  
		  
		  tokenAuthenticationFilter.setAuthecFailureHandler(authecFailureHandler());
		  tokenAuthenticationFilter.setAuthecSuccessHandler(authecSuccessHandler());
		  tokenAuthenticationFilter.setAuthecUnAuthecHandler(authecUnAuthecHandler());
		  
		  tokenAuthenticationFilter.setMaxSession(shiroConfigProperties.getMaxSession());
		  tokenAuthenticationFilter.setIsEnableSessionStrategy(shiroConfigProperties.getIsEnableSessionStrategy());
		  tokenAuthenticationFilter.setIsEnableCSRFToken(shiroConfigProperties.getIsEnableCSRFToken());
		  
		  
		  tokenAuthenticationFilter.setWeiChatAuthCallbackUrl(shiroWeiChatConfigProperties.getWeiChatAuthCallbackUrl());
		  tokenAuthenticationFilter.setWeiChatAppid(shiroWeiChatConfigProperties.getWeiChatAppid());
		  tokenAuthenticationFilter.setWeiChatSecret(shiroWeiChatConfigProperties.getWeiChatSecret());
		  
	      return tokenAuthenticationFilter;  
	  } 
	   private void setP(SnowyTokenAuthenticationFilter tokenAuthenticationFilter ){
		      tokenAuthenticationFilter.setLoginPortUrl(shiroConfigProperties.getLoginPortUrl());// from SnowyShiroAccessControlFilter
			  tokenAuthenticationFilter.setLoginSubmitUrl(shiroConfigProperties.getLoginSubmitUrl());
			  tokenAuthenticationFilter.setIsEnableSnowySSOClient(shiroConfigProperties.getSsoEnabled());
			  
			  tokenAuthenticationFilter.setUsernameParam(shiroConfigProperties.getUsernameParam());
			  tokenAuthenticationFilter.setPasswordParam(shiroConfigProperties.getPasswordParam());
			  tokenAuthenticationFilter.setRememberMeParam(shiroConfigProperties.getRememberMeParam());
			  tokenAuthenticationFilter.setLoginOrginParam(shiroConfigProperties.getLoginOrginParam());
			 
			  tokenAuthenticationFilter.setAuthecFailureHandler(authecFailureHandler());
			  tokenAuthenticationFilter.setAuthecSuccessHandler(authecSuccessHandler());
			  tokenAuthenticationFilter.setAuthecUnAuthecHandler(authecUnAuthecHandler());
			  
			  tokenAuthenticationFilter.setMaxSession(shiroConfigProperties.getMaxSession());
			  tokenAuthenticationFilter.setIsEnableSessionStrategy(shiroConfigProperties.getIsEnableSessionStrategy());
			  tokenAuthenticationFilter.setIsEnableCSRFToken(shiroConfigProperties.getIsEnableCSRFToken());
	   }
	  
	  
	  public CSRFTokenFilter csrfTokenFilter() {  
		 CSRFTokenFilter csrfTokenFilter = new  CSRFTokenFilter(); 
		 csrfTokenFilter.setCsrfAuthenticationFailureHandler(csrfFailureHandler());
		 csrfTokenFilter.setCsrfTokenName(shiroConfigProperties.getCsrfTokenName());
	     return csrfTokenFilter;  
	  } 
	  
	
	 
	  public SnowyCapchaProducerFilter capchaProducerFilter() {  
		  SnowyCapchaProducerFilter capchaFilter = new  SnowyCapchaProducerFilter();  
		  capchaFilter.setCaptchaImageUrl(shiroConfigProperties.getCaptchaImageUrl());
		  capchaFilter.setCaptchaProducer(producer);
	      return capchaFilter;  
	  } 
	  public SnowyLogoutFilter logoutFilter() {  
		  SnowyLogoutFilter logoutFilter = new  SnowyLogoutFilter(); 
		  logoutFilter.setAuthecLogoutHandler(authecLogoutHandler());
	      return logoutFilter;  
	  } 
		public SSOSyncClientFilter ssoSyncClientFilter() {
			SSOSyncClientFilter clientFilter=new SSOSyncClientFilter();
			if(ZStrUtil.hasText(shiroConfigProperties.getSsoClientSyncPath())){
				clientFilter.setSsoClientSyncPath(shiroConfigProperties.getSsoClientSyncPath());
			}
			return clientFilter;
		}
		public SSOSyncCenterfilter ssoSyncCenterfilter() {
			SSOSyncCenterfilter centerfilter= new SSOSyncCenterfilter();
			if(!ZObjectUtil.isEmpty(shiroConfigProperties.getAllowedSSOClientDomains())){
				centerfilter.setAllowedSSOClientDomains(shiroConfigProperties.getAllowedSSOClientDomains());
			}
			if(ZStrUtil.hasText(shiroConfigProperties.getSsoCenterSyncPath())){
				centerfilter.setSsoCenterSyncPath(shiroConfigProperties.getSsoCenterSyncPath());
			}
			
			return centerfilter;
		}
		
		
		  @Bean(name="jwtAuthenticationFailureHandler")  
		  public IAuthecFailureHandler jwtAuthenticationFailureHandler() {  
			  SimpleAuthecFailureHandler handler = new  SimpleAuthecFailureHandler(); 
			  handler.setDefaultAuthecFailureUrl(shiroConfigProperties.getDefaultAuthecSuccessUrl());
			  handler.setAuthecFailureForwardToDestination(shiroConfigProperties.getAuthecFailureForwardToDestination());
		      return handler;  
		  } 
		
	  @Bean(name="authecSuccessHandler")  
	  public IAuthecSuccessHandler authecSuccessHandler() {  
		  SimpleAuthecSuccessHandler handler = new  SimpleAuthecSuccessHandler();  
		  handler.setDefaultAuthecSuccessUrl(shiroConfigProperties.getDefaultAuthecSuccessUrl());
		  handler.setAuthecSuccessForwardToDestination(shiroConfigProperties.getAuthecSuccessForwardToDestination());
	      return handler;  
	  } 
	  @Bean(name="authecFailureHandler")  
	  public IAuthecFailureHandler authecFailureHandler() {  
		  SimpleAuthecFailureHandler handler = new  SimpleAuthecFailureHandler(); 
		  handler.setDefaultAuthecFailureUrl(shiroConfigProperties.getDefaultAuthecSuccessUrl());
		  handler.setAuthecFailureForwardToDestination(shiroConfigProperties.getAuthecFailureForwardToDestination());
	      return handler;  
	  } 
	  @Bean(name="authecLogoutHandler")  
	  public IAuthecLogoutHandler authecLogoutHandler() {  
		  SimpleAuthecLogoutHandler handler = new  SimpleAuthecLogoutHandler();
		  handler.setDefaultLogoutDirectUrl(shiroConfigProperties.getDefaultLogoutDirectUrl());
		  handler.setLogoutForwardToDestination(shiroConfigProperties.getLogoutForwardToDestination());
	      return handler;  
	  } 
	  @Bean(name="authecUnAuthecHandler")  
	  public IUnAuthecHandler authecUnAuthecHandler() {  
		  SimpleUnauthecHandler handler = new  SimpleUnauthecHandler();  
		  handler.setDefaultUnAuthecDirectUrl(shiroConfigProperties.getDefaultUnAuthecDirectUrl());
		  handler.setUnAuthecForwardToDestination(shiroConfigProperties.getUnAuthecForwardToDestination());
	      return handler;  
	  } 
	  
	  @Bean(name="unauthorizedHandler")  
	  public UnauthorizedHandler unauthorizedHandler() {  
		  SimpleUnauthorizedHandler handler = new  SimpleUnauthorizedHandler();  
		  handler.setDefaultUnauthorizedUrl(shiroConfigProperties.getDefaultUnauthorizedUrl());
		  handler.setForwardToDestination(shiroConfigProperties.getUnauthorizedForwardToDestination());
	      return handler;  
	  } 
	  
	 @Bean(name="csrfFailureHandler")  
	  public IAuthecFailureHandler csrfFailureHandler() {  
		  SimpleAuthecCsrfFailureHandler handler = new  SimpleAuthecCsrfFailureHandler();  
		  handler.setDefaultCsrfValidateFailureUrl(shiroConfigProperties.getDefaultCsrfValidateFailureUrl());
		  handler.setCsrfValidateForwardToDestination(shiroConfigProperties.getCsrfValidateForwardToDestination());
	      return handler;  
	  } 
}
